package com.powerdata.manage.background.service.impl;

import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import net.sf.oval.constraint.NotBlank;
import net.sf.oval.constraint.NotNull;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.powerdata.framework.annotation.log.LoggerProfile;
import com.powerdata.framework.base.PageModel;
import com.powerdata.framework.base.Query;
import com.powerdata.framework.pagehelper.BeanUtil;
import com.powerdata.framework.pagehelper.PagedResult;
import com.powerdata.framework.util.UUIDGenerator;
import com.powerdata.manage.background.dao.IUserMapper;
import com.powerdata.manage.background.model.User;
import com.powerdata.manage.background.service.IUserService;

@Service
public class UserServiceImpl implements IUserService {
	private static final Logger LOG = Logger.getLogger(UserServiceImpl.class);

	@Autowired
	private IUserMapper userMapper;
	
	@Resource
	private RedisTemplate<String, Object> redisTemplate; 
	
	/**
	 * 利用Oval框架验证参数不能为空
	 */
	@Override
	public User select(@NotBlank.List(value={@NotBlank(target="username"), @NotBlank(target="sex")}) User user) {
		LOG.info("验证Oval框架，验证参数传递--------------------------");
		return userMapper.select(user);
	}

	/**
	 * 利用Oval框架验证参数不能为空
	 */
	@Override
	public String insert(@NotNull User user) {
		String strId = UUIDGenerator.get32LowCaseUUID();
		user.setId(strId);
		userMapper.insert(user);
		return strId;
	}

	/**
	 * 利用Oval框架验证参数不能为空
	 */
	@Override
	public User getById(@NotBlank String id) {
		LOG.info("测试Oval框架，验证参数传递---------------------------");
		return null;
	}

	/*------测试自定义注解，切面记录日志----------------------------------*/
	@Override
	@LoggerProfile(methodNote="查询列表，测试切面记录日志")
	public List<User> queryList(User user) {
		return userMapper.queryList(user);
	}

	@Override
	public int findPageListCount(User user) {
		return userMapper.findPageListCount(user);
	}

	@Override
	//@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果，而是每次都会执行该方法，并将结果以键值对的形式存入指定的缓存中 
	//@CachePut(value="sysParamCache")
	//清除所有缓存
	//@CacheEvict(value="sysParamCache",allEntries=true,beforeInvocation=true)
	//清除指定缓存
	@CacheEvict(value="sysParamCache",key="#id",beforeInvocation=true)
	public int update(User user) {
		return userMapper.update(user);
	}

	@Override
	public int delete(String id) {
		return userMapper.delete(id);
	}

	@Override
	public PageInfo<User> findPageList(User user, PageModel pageModel) {
		PageHelper.startPage(pageModel.getPage(), pageModel.getLimit());
		List<User> userList = userMapper.queryList(user);
		PageInfo<User> pageInfo = new PageInfo<User>(userList);
		return pageInfo;
	}

	@Override
	public PageInfo<User> queryPageList(User user, Query query) {
		PageHelper.startPage(query.getPage(), query.getPageSize());
		List<User> userList = userMapper.queryList(user);
		PageInfo<User> pageInfo = new PageInfo<User>(userList);
		return pageInfo;
	}

	/**
	 * ehcache缓存
	 * key=#systemId+#merchantId+#businessType" 对象缓存的key值,需要保证唯一, 用的是Spring的 SpEL表达式
	 * value="sysParamCache":指的是ehcache.xml里的缓存名字
	 * 
	 * 若对刚才查询的表进行了增删改操作，这时我们再访问该查询方法，你会发现我们的数据并没有改变，
	 * 还是增删改操作之前的数据（因为缓存的生命还在），这里是不是问题呢？
	 * 此时我们需要对查询的缓存进行更新或删除。
	 * @CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果，而是每次都会执行该方法，并将结果以键值对的形式存入指定的缓存中 
	 * @CachePut(value="sysParamCache")
	 * 清除所有缓存
	 * @CacheEvict(value="sysParamCache",allEntries=true,beforeInvocation=true)
	 * 清除指定缓存
	 * @CacheEvict(value="sysParamCache",key="#id",beforeInvocation=true)
	 */
	@Override
	@Cacheable(value="sysParamCache", key="#user.username")
	public PageModel<User> findPage(User user, PageModel pageModel) {
		PageHelper.startPage(pageModel.getPage(), pageModel.getLimit());
		List<User> userList = userMapper.queryList(user);
		PageInfo<User> pageInfo = new PageInfo<User>(userList);
		PageModel<User> page = new PageModel<User>(pageInfo.getPageNum(),pageInfo.getPageSize(),(int)pageInfo.getTotal(),pageInfo.getList());
		LOG.info("测试查询缓存。。。。。。。。。。。。。。。。。。。");
		return page;
	}

	@Override
	public Page<User> queryPage(User user, Query query) {
		PageHelper.startPage(query.getPage(), query.getPageSize());
		List<User> userList = userMapper.queryList(user);
		Page<User> page = (Page<User>)userList;
		return page;
	}

	@Override
	public PagedResult<User> queryByPage(User user, Query query) {
		PageHelper.startPage(query.getPage(), query.getPageSize());
		List<User> userList = userMapper.queryList(user);
		return BeanUtil.toPagedResult(userList);
	}

	@Override
	public User queryRedisData(User user) {
		User userInfo = null;
		if (redisTemplate.hasKey(user.getUsername())) {
			LOG.info("测试redis，从redis中取数据："+JSON.toJSONString(redisTemplate.opsForValue().get(user.getUsername())));
			userInfo = (User) redisTemplate.opsForValue().get(user.getUsername());
			redisTemplate.delete(userInfo.getUsername());
			return userInfo;
		}
		LOG.info("测试redis，从数据中查询数据。。。。。。。。。。。。。。。。。");
		userInfo = this.select(user);
		redisTemplate.opsForValue().set(userInfo.getUsername(), userInfo, 10, TimeUnit.SECONDS);
		return userInfo;
	}
	
}
